/**
 * @file    W25Q128_Test.c
 * @brief   W25Q128 双芯片驱动测试示例
 * @author  开发者
 * @version 1.0
 * @date    2025-08-22
 */

#include "main.h"
#include "Dri_SPI.h"
#include "Int_W25Q128.h"
#include "Com_Debug.h"

/* 全局设备实例 */
W25Q_Device_t g_flash_device1;  // 第一颗W25Q128 (F_CS1)
W25Q_Device_t g_flash_device2;  // 第二颗W25Q128 (F_CS2)
W25Q_Volume_t g_flash_volume;   // 逻辑卷(32MB)

/* 测试缓冲区 */
uint8_t test_write_buffer[512];
uint8_t test_read_buffer[512];

/**
 * @brief 初始化W25Q128双芯片系统
 * @return 0-成功, 其他-失败
 */
int W25Q128_System_Init(void)
{
    int ret;
    uint32_t jedec_id;
    
    /* 初始化SPI2 */
    Dri_SPI_Init();
    Dri_SPI_Start();
    
    Com_Debug_Printf("W25Q128双芯片系统初始化...\r\n");
    
    /* 初始化第一颗芯片 */
    ret = W25Q_Init(&g_flash_device1, F_CS1_PORT, F_CS1_PIN);
    if (ret != 0)
    {
        Com_Debug_Printf("第一颗W25Q128初始化失败: %d\r\n", ret);
        return -1;
    }
    
    Com_Debug_Printf("第一颗W25Q128初始化成功, JEDEC ID: 0x%06X\r\n", g_flash_device1.jedec_id);
    
    /* 初始化第二颗芯片 */
    ret = W25Q_Init(&g_flash_device2, F_CS2_PORT, F_CS2_PIN);
    if (ret != 0)
    {
        Com_Debug_Printf("第二颗W25Q128初始化失败: %d\r\n", ret);
        return -2;
    }
    
    Com_Debug_Printf("第二颗W25Q128初始化成功, JEDEC ID: 0x%06X\r\n", g_flash_device2.jedec_id);
    
    /* 初始化逻辑卷 */
    ret = W25Q_VolumeInit(&g_flash_volume, &g_flash_device1, &g_flash_device2);
    if (ret != 0)
    {
        Com_Debug_Printf("逻辑卷初始化失败: %d\r\n", ret);
        return -3;
    }
    
    Com_Debug_Printf("逻辑卷初始化成功, 总容量: %d MB\r\n", g_flash_volume.total_capacity / (1024*1024));
    
    return 0;
}

/**
 * @brief 单芯片读写测试
 * @param dev 设备指针
 * @param device_name 设备名称
 * @return 0-成功, 其他-失败
 */
int W25Q128_Single_Device_Test(W25Q_Device_t* dev, const char* device_name)
{
    int ret;
    uint32_t test_addr = 0x1000; // 测试地址4KB
    uint32_t test_size = 256;    // 测试大小256字节
    uint32_t i;
    
    Com_Debug_Printf("\r\n=== %s 单芯片测试 ===\r\n", device_name);
    
    /* 准备测试数据 */
    for (i = 0; i < test_size; i++)
    {
        test_write_buffer[i] = (uint8_t)(i & 0xFF);
    }
    
    /* 擦除测试扇区 */
    Com_Debug_Printf("擦除扇区 0x%X...\r\n", test_addr);
    ret = W25Q_SectorErase(dev, test_addr);
    if (ret != 0)
    {
        Com_Debug_Printf("扇区擦除失败: %d\r\n", ret);
        return -1;
    }
    
    /* 验证擦除结果 */
    ret = W25Q_FastRead(dev, test_addr, test_read_buffer, test_size);
    if (ret != 0)
    {
        Com_Debug_Printf("读取数据失败: %d\r\n", ret);
        return -2;
    }
    
    for (i = 0; i < test_size; i++)
    {
        if (test_read_buffer[i] != 0xFF)
        {
            Com_Debug_Printf("擦除验证失败, 地址0x%X: 0x%02X\r\n", test_addr + i, test_read_buffer[i]);
            return -3;
        }
    }
    Com_Debug_Printf("扇区擦除验证成功\r\n");
    
    /* 写入测试数据 */
    Com_Debug_Printf("写入测试数据...\r\n");
    ret = W25Q_WriteData(dev, test_addr, test_write_buffer, test_size);
    if (ret != 0)
    {
        Com_Debug_Printf("写入数据失败: %d\r\n", ret);
        return -4;
    }
    
    /* 读取并验证数据 */
    Com_Debug_Printf("读取并验证数据...\r\n");
    ret = W25Q_FastRead(dev, test_addr, test_read_buffer, test_size);
    if (ret != 0)
    {
        Com_Debug_Printf("读取数据失败: %d\r\n", ret);
        return -5;
    }
    
    for (i = 0; i < test_size; i++)
    {
        if (test_read_buffer[i] != test_write_buffer[i])
        {
            Com_Debug_Printf("数据验证失败, 地址0x%X: 写入0x%02X, 读取0x%02X\r\n", 
                           test_addr + i, test_write_buffer[i], test_read_buffer[i]);
            return -6;
        }
    }
    
    Com_Debug_Printf("%s 单芯片测试成功!\r\n", device_name);
    return 0;
}

/**
 * @brief 逻辑卷跨芯片测试
 * @return 0-成功, 其他-失败
 */
int W25Q128_Volume_Cross_Chip_Test(void)
{
    int ret;
    uint32_t test_addr = 16*1024*1024 - 128; // 跨芯片边界地址
    uint32_t test_size = 256;                // 跨越两个芯片
    uint32_t i;
    
    Com_Debug_Printf("\r\n=== 逻辑卷跨芯片测试 ===\r\n");
    Com_Debug_Printf("测试地址: 0x%X, 大小: %d 字节\r\n", test_addr, test_size);
    
    /* 准备测试数据 */
    for (i = 0; i < test_size; i++)
    {
        test_write_buffer[i] = (uint8_t)((i + 0xAA) & 0xFF);
    }
    
    /* 擦除相关扇区 */
    Com_Debug_Printf("擦除跨芯片扇区...\r\n");
    ret = W25Q_VolumeSectorErase(&g_flash_volume, test_addr);
    if (ret != 0)
    {
        Com_Debug_Printf("第一个扇区擦除失败: %d\r\n", ret);
        return -1;
    }
    
    ret = W25Q_VolumeSectorErase(&g_flash_volume, test_addr + 256);
    if (ret != 0)
    {
        Com_Debug_Printf("第二个扇区擦除失败: %d\r\n", ret);
        return -2;
    }
    
    /* 写入跨芯片数据 */
    Com_Debug_Printf("写入跨芯片数据...\r\n");
    ret = W25Q_VolumeWrite(&g_flash_volume, test_addr, test_write_buffer, test_size);
    if (ret != 0)
    {
        Com_Debug_Printf("跨芯片写入失败: %d\r\n", ret);
        return -3;
    }
    
    /* 读取并验证跨芯片数据 */
    Com_Debug_Printf("读取并验证跨芯片数据...\r\n");
    ret = W25Q_VolumeRead(&g_flash_volume, test_addr, test_read_buffer, test_size);
    if (ret != 0)
    {
        Com_Debug_Printf("跨芯片读取失败: %d\r\n", ret);
        return -4;
    }
    
    for (i = 0; i < test_size; i++)
    {
        if (test_read_buffer[i] != test_write_buffer[i])
        {
            Com_Debug_Printf("跨芯片数据验证失败, 偏移%d: 写入0x%02X, 读取0x%02X\r\n", 
                           i, test_write_buffer[i], test_read_buffer[i]);
            return -5;
        }
    }
    
    Com_Debug_Printf("逻辑卷跨芯片测试成功!\r\n");
    return 0;
}

/**
 * @brief 性能测试
 * @return 0-成功, 其他-失败
 */
int W25Q128_Performance_Test(void)
{
    int ret;
    uint32_t test_addr = 0x10000; // 64KB地址
    uint32_t test_size = 4096;    // 4KB测试
    uint32_t i;
    
    Com_Debug_Printf("\r\n=== 性能测试 ===\r\n");
    
    /* 准备测试数据 */
    for (i = 0; i < test_size; i++)
    {
        test_write_buffer[i] = (uint8_t)(i & 0xFF);
    }
    
    /* 擦除测试扇区 */
    ret = W25Q_SectorErase(&g_flash_device1, test_addr);
    if (ret != 0)
    {
        Com_Debug_Printf("性能测试扇区擦除失败: %d\r\n", ret);
        return -1;
    }
    
    /* 写入性能测试 */
    Com_Debug_Printf("开始4KB写入性能测试...\r\n");
    // 这里可以添加时间测量代码
    ret = W25Q_WriteData(&g_flash_device1, test_addr, test_write_buffer, test_size);
    if (ret != 0)
    {
        Com_Debug_Printf("性能测试写入失败: %d\r\n", ret);
        return -2;
    }
    Com_Debug_Printf("4KB写入完成\r\n");
    
    /* 读取性能测试 */
    Com_Debug_Printf("开始4KB读取性能测试...\r\n");
    // 这里可以添加时间测量代码
    ret = W25Q_FastRead(&g_flash_device1, test_addr, test_read_buffer, test_size);
    if (ret != 0)
    {
        Com_Debug_Printf("性能测试读取失败: %d\r\n", ret);
        return -3;
    }
    Com_Debug_Printf("4KB读取完成\r\n");
    
    /* 验证数据 */
    for (i = 0; i < test_size; i++)
    {
        if (test_read_buffer[i] != test_write_buffer[i])
        {
            Com_Debug_Printf("性能测试数据验证失败\r\n");
            return -4;
        }
    }
    
    Com_Debug_Printf("性能测试成功!\r\n");
    return 0;
}

/**
 * @brief W25Q128完整测试流程
 * @return 0-成功, 其他-失败
 */
int W25Q128_Full_Test(void)
{
    int ret;
    
    Com_Debug_Printf("\r\n========== W25Q128双芯片完整测试 ==========\r\n");
    
    /* 系统初始化 */
    ret = W25Q128_System_Init();
    if (ret != 0)
    {
        Com_Debug_Printf("系统初始化失败: %d\r\n", ret);
        return ret;
    }
    
    /* 单芯片测试 */
    ret = W25Q128_Single_Device_Test(&g_flash_device1, "第一颗芯片");
    if (ret != 0)
    {
        Com_Debug_Printf("第一颗芯片测试失败: %d\r\n", ret);
        return ret;
    }
    
    ret = W25Q128_Single_Device_Test(&g_flash_device2, "第二颗芯片");
    if (ret != 0)
    {
        Com_Debug_Printf("第二颗芯片测试失败: %d\r\n", ret);
        return ret;
    }
    
    /* 跨芯片测试 */
    ret = W25Q128_Volume_Cross_Chip_Test();
    if (ret != 0)
    {
        Com_Debug_Printf("跨芯片测试失败: %d\r\n", ret);
        return ret;
    }
    
    /* 性能测试 */
    ret = W25Q128_Performance_Test();
    if (ret != 0)
    {
        Com_Debug_Printf("性能测试失败: %d\r\n", ret);
        return ret;
    }
    
    Com_Debug_Printf("\r\n========== 所有测试通过! ==========\r\n");
    return 0;
}
